#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@File: RemoteSSHClient.py
@Author: lijk34925 
@Date: 2025/5/14 20:16
@desc: 请补充本模块功能说明
"""
import re

import paramiko

from AmlScripts.amlConfig import amlConfig
from BladeFerm.databases.DealSql.EnvConfig import EnvConfig
from BladeFerm.Lib.LocalLogger import logger_local as logger
from uploadBladeCase.ReadLoaclConfig import tip_ding


class RemoteSSHClient(object):
    def __init__(self, config):
        self.systemConfig = config
        self.env_name = config.get("env", "unKnow")
        self.envConfig = None
        self.envTitle = None
        self.machineConfig = dict()
        self.SSHClient = None
        self.root_path = '/opt'

    def __init_client(self, envName=None, root_path=None):
        if envName or (envName != self.env_name) or (not self.envConfig):
            self.env_name = envName
            self.envConfig = EnvConfig(envName, config=self.systemConfig)
            self.envTitle = self.envConfig.title
            self.machineConfig = self.envConfig.machineConfig
        if root_path:
            self.root_path = root_path
        if envName != self.env_name or (not self.SSHClient) or (self.root_path != root_path):
            self.__close_client()
            self.SSHClient = paramiko.SSHClient()
            self.SSHClient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.SSHClient.connect(self.machineConfig.get('ip'),
                                   username=self.machineConfig.get('user'),
                                   password=self.machineConfig.get('password'))
        logger.info(f'{self.envTitle} 的SSH连接已建立')

    def __close_client(self):
        if self.SSHClient:
            self.SSHClient.close()
        logger.info(f'{self.envTitle} 的SSH连接已关闭')

    def __act_command(self, command, root_path=None):
        if root_path:
            self.root_path = root_path
        run_cmd = f"cd {self.root_path} && {command}"
        logger.info(f"执行命令：{run_cmd}")
        stdin, stdout, stderr = self.SSHClient.exec_command(run_cmd)
        # 读取并保存输出内容
        output = stdout.read().decode().strip()
        error = stderr.read().decode().strip()
        logger.info(f"输出信息：\n{output}")
        if error:
            logger.warning(f"错误信息：\n{error}")
        # 返回输出内容，而非原始stdout对象
        return output, error

    def __read_df_h(self):
        cmd = "df -h"
        stdout, stderr = self.__act_command(cmd)
        result = list()
        head_title = ['Filesystem', 'Size', 'Used', 'Avail', 'Use', 'MountedOn', 'Percentage']
        for index, line in enumerate(stdout.split('\n')):
            if index > 0:
                lines = line.split()
                Percentage = lines[-2].replace('%', '')
                lines.append(Percentage)
                result.append(dict(zip(head_title, lines)))
        logger.info(f"{self.envTitle}的磁盘使用信息：{result}")
        return result

    def __read_cpu_h(self):
        cmd = 'sar -u 1 3'
        stdout, stderr = self.__act_command(cmd)
        if re.search(r"command not fund", stderr, re.I):
            cmd_install = 'yum install -y sysstat'
            self.__act_command(cmd_install)
            stdout, stderr = self.__act_command(cmd)
        result = list()
        head_title = ['title', 'title', 'Percentage', 'Nice', 'system', 'iowait', 'steal', 'idle']
        for index, line in enumerate(stdout.split('\n')):
            if index > 0:
                lines = line.split()
                result.append(dict(zip(head_title, lines)))
        result = [result[-1]] if result else []
        logger.info(f"{self.envTitle}的CPU使用信息：{result}")
        return result

    def __read_free_h(self):
        cmd = "free -h"
        stdout, stderr = self.__act_command(cmd)
        result = list()
        head_title = ['title', 'total', 'Used', 'free', 'shared', 'buff', 'available', 'Percentage']
        for index, line in enumerate(stdout.split('\n')):
            if index > 0:
                lines = line.split()
                new_lies = [re.match(r"\d*\.?\d+", unit, re.I).group(0) if re.match(r"\d*\.?\d+", unit,
                                                                                    re.I) else unit for unit in lines]
                Percentage = round(float(new_lies[2]) / float(new_lies[1]) * 100, 2)
                lines.append(Percentage)
                result.append(dict(zip(head_title, lines)))
        logger.info(f"{self.envTitle}的内存信息：{result}")
        return result

    @staticmethod
    def __judge_use_percentage(target, use_info: list, limit: int = 80):
        judge_rsult = True
        res_title = None
        if not use_info:
            judge_rsult = False
            res_title = f"{target}信息获取失败"
            logger.error(res_title)
            return judge_rsult, res_title
        for info in use_info:
            percentage = info.get('Percentage')
            if percentage and isinstance(percentage, str):
                percentage = float(percentage)
            if percentage and percentage > limit:
                judge_rsult = False
                res_title = f"{target}使用率超过{limit}%，当前使用率为{percentage}%"
                break
        logger.warning(f"资源阈值判断结果：{judge_rsult}，提示信息：{res_title}")
        return judge_rsult, res_title

    def judge_use_percentage(self, envName=None, limit: int = 80):
        """
        判断资源使用率是否超过阈值
        :param envName:
        :param limit:
        :return:
        """
        self.__init_client(envName)
        df_h_res = self.__read_df_h()
        df_judge_rsult, df_res_title = self.__judge_use_percentage('磁盘', df_h_res, limit)
        cpu_h_res = self.__read_cpu_h()
        cpu_judge_rsult, cpu_res_title = self.__judge_use_percentage('CPU', cpu_h_res, limit)
        free_h_res = self.__read_free_h()
        free_judge_rsult, free_res_title = self.__judge_use_percentage('内存', free_h_res, limit)
        all_result_title = f"### {self.envTitle} 环境资源检查结果通知：\n"
        if not df_judge_rsult:
            all_result_title += f"{df_res_title} \n"
        if not cpu_judge_rsult:
            all_result_title += f"{cpu_res_title} \n"
        if not free_judge_rsult:
            all_result_title += f"{free_res_title} \n"
        if (not df_judge_rsult) or (not cpu_judge_rsult) or (not free_judge_rsult):
            logger.warning(f"资源超出阈值：{all_result_title}")
            tip_ding(all_result_title)
        else:
            logger.info(f"资源正常，未超出阈值！")
        if not df_judge_rsult:
            self.clear_history_zip()
        self.__close_client()

    def clear_history_zip(self, envName=None):
        """
        清理历史包
        """
        clear_zip_commands = ['wget http://10.20.163.236:8015/static/shell/BatchDeleteZip.sh',
                              'chmod +x BatchDeleteZip.sh',
                              'sh ./BatchDeleteZip.sh',
                              'rm -rf BatchDeleteZip.sh']
        self.__init_client(envName, root_path='/opt')
        result = list()
        for line in clear_zip_commands:
            stdout, stderr = self.__act_command(line)
            result.append((stdout, stderr))
        message = f"### 通知：\n {self.envTitle} 清理历史包完成！ \n"
        tip_ding(message)
        self.__close_client()
        return result

    def batch_check_task(self, envs, limit):
        for env in envs:
            try:
                self.judge_use_percentage(env, limit)
            except Exception as e:
                logger.error(f"环境{env}检查失败，错误信息：{e}")
                message = f"### 环境{env}检查，异常通知：\n {e}"
                tip_ding(message)
        logger.info("所有环境检查完成！")


if __name__ == '__main__':
    ssh = RemoteSSHClient(amlConfig)
    ssh.judge_use_percentage('mysql_auto', 75)